package cc.comac.mom.config;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.UUID;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.IOUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import com.aliyun.oss.OSSClient;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.CannedAccessControlList;
import com.aliyun.oss.model.CreateBucketRequest;
import com.aliyun.oss.model.GeneratePresignedUrlRequest;
import com.aliyun.oss.model.OSSObject;
import com.aliyun.oss.model.PutObjectRequest;
import com.aliyun.oss.model.PutObjectResult;

@Service
public class OSSService {

    @Value("${oss.endpoint}")
    private String endpoint;

    @Value("${ons.accessKey}")
    private String accessKeyId;

    @Value("${ons.secretKey}")
    private String accessKeySecret;

    @Value("${oss.bucketName}")
    private String bucketName;

    private OSSClient ossClient;

    @SuppressWarnings("deprecation")
    
	@PostConstruct
    public void init() {
        // 创建OSSClient实例。
        ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
    }
// oss 上传文件
    public String uploadFileOss(MultipartFile file) throws IOException {
    	 String fileUrl= "";
    	// Endpoint以杭州为例，其它Region请按实际情况填写。
        String endpoint = this.endpoint;
        // 阿里云主账号AccessKey拥有所有API的访问权限，风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维，请登录  https://ram.console.aliyun.com 创建RAM账号。
        String accessKeyId = this.accessKeyId;
        String accessKeySecret = this.accessKeySecret;
        //创建的bucket名
        String bucketName = this.bucketName;
		//获取文件名
        String originalFilename = file.getOriginalFilename();
        //获取文件后缀名
        String substring = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);
        //使用uuid作为文件名防止重复
        String uuid = UUID.randomUUID().toString().replaceAll("-", "");
        String fileName = uuid+"."+substring;
        final File tempFile = File.createTempFile(uuid, substring);
        //MultipartFile  转换为 File
        file.transferTo(tempFile);
        // 创建OSSClient实例。
        @SuppressWarnings("deprecation")
		OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
        try {
            //容器不存在，就创建
            if(! ossClient.doesBucketExist(bucketName)){
                ossClient.createBucket(bucketName);
                CreateBucketRequest createBucketRequest = new CreateBucketRequest(bucketName);
                createBucketRequest.setCannedACL(CannedAccessControlList.PublicRead);
                ossClient.createBucket(createBucketRequest);
            }
            String fileHost = "upload"+File.separator+"equip";
            //上传文件
            //File file1 = multipartFileToFile(file);
            //创建文件路径
            fileUrl= fileHost+File.separator+fileName;
            PutObjectResult result = ossClient.putObject(new PutObjectRequest(bucketName, fileUrl, tempFile));
            //设置权限 这里是公开读
            ossClient.setBucketAcl(bucketName,CannedAccessControlList.PublicRead);
            if(null != result){
                System.out.println("==========>OSS文件上传成功,OSS地址："+fileUrl);
                return fileUrl;
            }
        }catch (OSSException oe){
            throw new RuntimeException(oe.getMessage());
        }catch (Exception e) {
            e.printStackTrace();
        } finally {
            //关闭
            ossClient.shutdown();
        }
        //删除临时生成的文件
        deleteFile(tempFile);
        return fileUrl;
    }
    
    private void deleteFile(File... files) {
        for (File file : files) {
            if (file.exists()) {
                file.delete();
            }
        }
    }

// oss下载文件    
    public  void downFileFromOSS(HttpServletResponse response, String url, String fileName) throws IOException  {
    	
    	// 获取OSS服务器上的全路径
    	URL url2 = getUrl(url);
    	 OSSObject obj = ossClient.getObject(url2, new HashMap<>());
         // 第六步，将文件存到浏览器设置的下载位置
         String filename = fileName;
         response.setContentType("application/ms-excel;charset=UTF-8");
         response.setHeader("Content-Disposition", "attachment;filename="
                 .concat(String.valueOf(URLEncoder.encode(filename, "UTF-8"))));
         OutputStream out = response.getOutputStream();
         try {
             IOUtils.copy(obj.getObjectContent(), out);
             String str = "下载" + fileName + "成功！";
             System.out.println(str);
         } catch (Exception e) {
             e.printStackTrace();
             String str1 = "下载" + fileName + "失败！";
             System.out.println(str1);
         } finally {
             out.close();
         }
		
	}

    /**
     * 参数：path: oss文件的路径+文件名
     * 返回： 获取oss上面的全路径
     * **/
    public  URL getUrl(String path){
        // 设置URL过期时间为1小时
        Date expiration = new Date(new Date().getTime() + 3600 * 1000);
        GeneratePresignedUrlRequest generatePresignedUrlRequest ;
        generatePresignedUrlRequest =new GeneratePresignedUrlRequest(bucketName, path);
        generatePresignedUrlRequest.setExpiration(expiration);
        URL url = ossClient.generatePresignedUrl(generatePresignedUrlRequest);
        return url;
    }
     
    // 预览图片
    public InputStream getFileByPathFromOss(String path) {
    	URL url = getUrl(path);
    	OSSObject obj = ossClient.getObject(url, new HashMap<>());
    	InputStream objectContent = obj.getObjectContent();
    	return objectContent;
    }

    public String updateSheet(ByteArrayInputStream file,String fileName) {
        String prefixKey = "template/qar/";
        // 上传文件。
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
        String name = fileName  + sdf.format(new Date());//文件名称
        prefixKey = prefixKey + name + ".xlsx";
        // 创建OSSClient实例。
        // 判断文件是否存在。doesObjectExist还有一个参数isOnlyInOSS，如果为true则忽略302重定向或镜像；如果为false，则考虑302重定向或镜像。
        boolean found = ossClient.doesObjectExist(bucketName, prefixKey);
        if (found) {
            try {
                Thread.sleep(10);
            } catch (Exception e) {
            }
            String newfileName = fileName  + sdf.format(new Date());
            prefixKey = prefixKey + newfileName + ".xlsx";
            return getUrl(file, prefixKey, ossClient);
        } else {
            return getUrl(file, prefixKey, ossClient);
        }
    }
    
    private String getUrl(ByteArrayInputStream file, String prefixKey, OSSClient ossClient) {
        // 设置URL过期时间。
    	Date expiration = new Date(new Date().getTime() + 3600 * 1000);
        // 生成以GET方法访问的签名URL，访客可以直接通过浏览器访问相关内容。
        URL url = ossClient.generatePresignedUrl(bucketName, prefixKey, expiration);
        try {
            ossClient.putObject(this.bucketName, prefixKey, file);
        } finally {
            // 关闭OSSClient。
            ossClient.shutdown();
        }
        return url.toString();
    }
    
    
	 /** 
     * 文件导出
     * @param path  从oss上导出数据
     * @param response 
     */  
    public void export(HttpServletResponse response, String url, String fileName) throws IOException {
        OSSObject obj = ossClient.getObject(new URL(url), new HashMap<>());
        // 第六步，将文件存到浏览器设置的下载位置
        String filename = fileName + ".xlsx";
        response.setContentType("application/ms-excel;charset=UTF-8");
        response.setHeader("Content-Disposition", "attachment;filename="
                .concat(String.valueOf(URLEncoder.encode(filename, "UTF-8"))));
        OutputStream out = response.getOutputStream();
        try {
            IOUtils.copy(obj.getObjectContent(), out);
            String str = "导出" + fileName + "成功！";
            System.out.println(str);
        } catch (Exception e) {
            e.printStackTrace();
            String str1 = "导出" + fileName + "失败！";
            System.out.println(str1);
        } finally {
            out.close();
        }
    }
    
    // 通过HSSFWorkbook导出数据
    public void exportExcel (HSSFWorkbook workBook,HttpServletResponse response,String fileName) {
    	
    	ByteArrayOutputStream baos = new ByteArrayOutputStream();
    	try {
			workBook.write(baos);
			ByteArrayInputStream swapStream = new ByteArrayInputStream(baos.toByteArray());
	    	// 通过生成的excel,上传excel文件，并返回url
	        String url = updateSheet(swapStream,fileName);
	        export(response, url, fileName);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
        
    }
}
